package org.jeecg.modules.business.doc.business.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.BeanUtil;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.modules.basic.material.entity.BasicMaterial;
import org.jeecg.modules.basic.material.mapper.BasicMaterialMapper;
import org.jeecg.modules.basic.material.service.IBasicMaterialService;
import org.jeecg.modules.basic.plant.entity.WmsSapWarehouseMap;
import org.jeecg.modules.basic.plant.mapper.WmsSapWarehouseMapMapper;
import org.jeecg.modules.basic.print.entity.PrintConfig;
import org.jeecg.modules.basic.print.service.IPrintConfigService;
import org.jeecg.modules.basic.saplocation.entity.WmsSapLocation;
import org.jeecg.modules.basic.saplocation.service.IWmsSapLocationService;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouse;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseArea;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseAreaLocation;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaLocationService;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaService;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseService;
import org.jeecg.modules.basic.warehouseGroup.mapper.WmsBasicWarehouseGroupUserMapper;
import org.jeecg.modules.business.doc.business.entity.WmsInReceipt;
import org.jeecg.modules.business.doc.business.entity.WmsInReceiptMaterial;
import org.jeecg.modules.business.doc.business.entity.dto.ListByWarehouseIdResponseVO;
import org.jeecg.modules.business.doc.business.entity.dto.ListWmsInReceiptDTO;
import org.jeecg.modules.business.doc.business.entity.dto.ListWmsInReceiptDetailDTO;
import org.jeecg.modules.business.doc.business.entity.dto.ValidMaterialAndWarehouseTypeDTO;
import org.jeecg.modules.business.doc.business.entity.vo.WmsInReceiptQueryVO;
import org.jeecg.modules.business.doc.business.mapper.WmsInReceiptMapper;
import org.jeecg.modules.business.doc.business.mapper.WmsInReceiptMaterialMapper;
import org.jeecg.modules.business.doc.business.service.IWmsInReceiptService;
import org.jeecg.modules.business.doc.business.vo.WarehousingStrategyOneParamVO;
import org.jeecg.modules.business.doc.business.vo.WarehousingStrategyOneVO;
import org.jeecg.modules.business.doc.business.vo.WarehousingStrategyParamVO;
import org.jeecg.modules.business.doc.business.vo.WmsInReceiptMaterialResponseVO;
import org.jeecg.modules.business.doc.outbound.entity.WmsOutReceipt;
import org.jeecg.modules.business.doc.outbound.entity.vo.UnCreateInVO;
import org.jeecg.modules.business.doc.outbound.entity.vo.UnCreateReqVO;
import org.jeecg.modules.business.doc.outbound.mapper.WmsOutReceiptMapper;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTask;
import org.jeecg.modules.business.outbound.entity.WmsOutReceiptTaskMaterial;
import org.jeecg.modules.business.outbound.mapper.WmsOutReceiptTaskMapper;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskMaterialService;
import org.jeecg.modules.business.outbound.service.IWmsOutReceiptTaskService;
import org.jeecg.modules.business.repertory.entity.WmsRepertory;
import org.jeecg.modules.business.repertory.mapper.WmsRepertoryMapper;
import org.jeecg.modules.business.third.service.ISapOperateService;
import org.jeecg.modules.business.transfer.entity.WmsMoveReceipt;
import org.jeecg.modules.business.transfer.mapper.WmsMoveReceiptMapper;
import org.jeecg.modules.business.warehouse.entity.WmsInReceiptTask;
import org.jeecg.modules.business.warehouse.entity.WmsInReceiptTaskMaterial;
import org.jeecg.modules.business.warehouse.mapper.WmsInReceiptTaskMapper;
import org.jeecg.modules.business.warehouse.mapper.WmsInReceiptTaskMaterialMapper;
import org.jeecg.modules.business.warehouse.service.IWmsInReceiptTaskService;
import org.jeecg.modules.dock.entity.WmsLightConfig;
import org.jeecg.modules.dock.entity.dto.request.InventoryAdjustRequestDTO;
import org.jeecg.modules.dock.entity.dto.response.InventoryUpdateResponseDTO;
import org.jeecg.modules.dock.entity.light.request.LightRequestVO;
import org.jeecg.modules.dock.mapper.WmsLightConfigMapper;
import org.jeecg.modules.dock.service.LightIBSDockingService;
import org.jeecg.modules.dock.service.SapDockingRepeaterService;
import org.jeecg.modules.flow.callback.enums.DocumentStatusEnum;
import org.jeecg.modules.flow.callback.enums.SimpleDocumentTypeEnum;
import org.jeecg.modules.flow.callback.enums.TransferStatusEnum;
import org.jeecg.modules.flow.callback.inbound.order.InBoundBeanUtils;
import org.jeecg.modules.flow.sys.service.WorkFlowService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 入库单
 * @Author: jeecg-boot
 * @Date: 2023-07-31
 * @Version: V1.0
 */
@Slf4j
@Service
public class WmsInReceiptServiceImpl extends ServiceImpl<WmsInReceiptMapper, WmsInReceipt> implements IWmsInReceiptService {

    private static final String ONE = "1";
    private static final String TWO = "2";
    @Resource
    private WmsInReceiptMapper wmsInReceiptMapper;
    @Resource
    private WmsInReceiptMaterialMapper wmsInReceiptMaterialMapper;
    @Resource
    private WmsInReceiptTaskMapper wmsInReceiptTaskMapper;
    @Resource
    private WmsInReceiptTaskMaterialMapper wmsInReceiptTaskMaterialMapper;
    @Resource
    private BasicMaterialMapper basicMaterialMapper;

    @Autowired
    private IBasicMaterialService basicMaterialService;
    @Resource
    private WmsOutReceiptTaskMapper wmsOutReceiptTaskMapper;
    @Resource
    private WmsOutReceiptMapper wmsOutReceiptMapper;
    @Resource
    private WmsMoveReceiptMapper wmsMoveReceiptMapper;
    @Resource
    private ISysBaseAPI iSysBaseAPI;
    @Autowired
    private IWmsBasicWarehouseAreaLocationService locationService;
    @Autowired
    private IWmsBasicWarehouseAreaService areaService;
    @Autowired
    private IWmsBasicWarehouseService warehouseService;
    @Autowired
    private IWmsOutReceiptTaskService outReceiptTaskService;
    @Autowired
    private IWmsOutReceiptTaskMaterialService outReceiptTaskMaterialService;
    @Resource
    private WmsRepertoryMapper repertoryMapper;
    @Resource
    private WmsLightConfigMapper lightConfigMapper;
    @Autowired
    private LightIBSDockingService lightIBSDockingService;

    @Resource
    private IWmsInReceiptTaskService wmsInReceiptTaskService;
    @Autowired
    private IPrintConfigService iPrintConfigService;
    @Autowired
    @Lazy
    private ISapOperateService sapOperateService;
    @Autowired
    @Lazy
    private InBoundBeanUtils inBoundBeanUtils;
    @Autowired
    @Lazy
    private WorkFlowService workFlowService;
    @Resource
    private WmsBasicWarehouseGroupUserMapper wmsBasicWarehouseGroupUserMapper;
    @Resource
    private WmsSapWarehouseMapMapper sapWarehouseMapMapper;
    @Resource
    private IWmsSapLocationService sapLocationService;
    @Resource
    @Lazy
    private SapDockingRepeaterService sapDockingRepeaterService;
    private final String[] deliveryType = {"R101","R105"};

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveMain(WmsInReceipt wmsInReceipt, List<WmsInReceiptMaterial> wmsInReceiptMaterialList) {
//        CommonUtil.validParamsNum((List) wmsInReceiptMaterialList, "warehouseQuantity", "assistQuantity", "outsideDiameter", "width", "width", "");
        wmsInReceiptMaterialList.forEach(one->{
            if (StrUtil.isBlank(one.getWmsBasicWarehouseId())){
                throw new JeecgBootException("入库单缺少必填参数: 仓库");
            }
        });
        //检验单据配置,回写任务物料明细
//        printConfigMaterialCanOtherWay(wmsInReceipt,wmsInReceiptMaterialList);
        //初始化入库单
        initInReceipt(wmsInReceipt);
        if (StrUtil.isBlank(wmsInReceipt.getDocumentCode())) {
            wmsInReceipt.setDocumentCode(FillRuleUtil.executeRule("rk_rule", new JSONObject()).toString());
        }
        //防止出现一样的单号,校验一下
        Long count = wmsInReceiptMapper.selectCount(new LambdaQueryWrapper<WmsInReceipt>()
                .eq(WmsInReceipt::getDocumentCode, wmsInReceipt.getDocumentCode())
        );
        if (count > 0){
            throw new JeecgBootException("入库单单据编号已经存在");
        }
        //设置过账状态
        TransferStatusEnum transferStatus = wmsInReceiptTaskService.getTransferStatusWhenSave(SimpleDocumentTypeEnum.IN_RECEIPT, wmsInReceipt.getDocumentType());
        wmsInReceipt.setTransferSapStatus(transferStatus.getCode());
        wmsInReceiptMapper.insert(wmsInReceipt);
        if (wmsInReceiptMaterialList != null && wmsInReceiptMaterialList.size() > 0) {
            int i = 1;
            for (WmsInReceiptMaterial entity : wmsInReceiptMaterialList) {
                //外键设置
                entity.setWmsInReceiptId(wmsInReceipt.getId());
                //更新序号
                if(StrUtil.isBlank(entity.getUpstreamLineNumber())){
                    entity.setUpstreamLineNumber(String.valueOf(i));
                    i++;
                }
//                initInReceiptMaterial(entity, wmsInReceipt.getWmsInReceiptTaskId());
                wmsInReceiptMaterialMapper.insert(entity);
                basicMaterialService.updateUsedState(entity.getWmsBasicMaterialId());
            }
        }
        String id = wmsInReceipt.getId();
        warehouseValid(wmsInReceipt.getId());
        return id;
    }
    /**
     * 检查单据配置是否配置了出入物料可不存在于任务中,如果配置了,并且入库单的物料种类(物料+批次号)比入库任务多,则在任务保存该物料
     */
    void printConfigMaterialCanOtherWay(WmsInReceipt wmsInReceipt, List<WmsInReceiptMaterial> wmsInReceiptMaterialList){
        PrintConfig printConfig = iPrintConfigService.getOne(new LambdaQueryWrapper<PrintConfig>()
                .eq(PrintConfig::getBusinessType, "document_type")
                .eq(PrintConfig::getDocumentType, wmsInReceipt.getDocumentType())
                .last("limit 1")
        );
        if (printConfig != null){
            if (printConfig.getMaterialCanOtherWay() != null){
                //勾上了出入库任务可不存在于任务中
                if (printConfig.getMaterialCanOtherWay() == 1){
                    //如果入库单有物料不存在入库任务中,在任务里反写上
                    for (WmsInReceiptMaterial inReceiptMaterial : wmsInReceiptMaterialList) {
                        LambdaQueryWrapper<WmsInReceiptTaskMaterial> queryWrapper = new LambdaQueryWrapper<>();
                        if (StrUtil.isNotBlank(inReceiptMaterial.getWmsBasicMaterialId())){
                            queryWrapper.eq(WmsInReceiptTaskMaterial::getWmsBasicMaterialId,inReceiptMaterial.getWmsBasicMaterialId());
                        }
                        queryWrapper.eq(WmsInReceiptTaskMaterial::getWmsInReceiptTaskId,wmsInReceipt.getWmsInReceiptTaskId());
                        queryWrapper.last("limit 1");
                        WmsInReceiptTaskMaterial taskMaterial = wmsInReceiptTaskMaterialMapper.selectOne(queryWrapper);
                        //该物料在对应的任务中不存在,就在任务里新增这个物料
                        if (ObjectUtil.isNull(taskMaterial)){
                            WmsInReceiptTaskMaterial wmsInReceiptTaskMaterial = cn.hutool.core.bean.BeanUtil.toBean(inReceiptMaterial, WmsInReceiptTaskMaterial.class);
                            wmsInReceiptTaskMaterial.setWmsInReceiptTaskId(wmsInReceipt.getWmsInReceiptTaskId());
                            wmsInReceiptTaskMaterial.setPlanQuantity(inReceiptMaterial.getWarehouseQuantity());
                            wmsInReceiptTaskMaterial.setPlanQuantityAssist(inReceiptMaterial.getWarehouseQuantityAssist());
                            wmsInReceiptTaskMaterialMapper.insert(wmsInReceiptTaskMaterial);
                        }
                    }
                }
            }
        }
    }

    /**
     * 创建入库单获取入库任务的公有属性
     */
    void initInReceipt(WmsInReceipt wmsInReceipt) {
        //获取所属任务的字段(前端不传就去任务里获取相同的字段值)
        WmsInReceiptTask wmsInReceiptTask = wmsInReceiptTaskMapper.selectById(wmsInReceipt.getWmsInReceiptTaskId());
        if (ObjectUtil.isNotEmpty(wmsInReceiptTask)) {
            if (StrUtil.isEmpty(wmsInReceipt.getOriginalSystem())) {
                wmsInReceipt.setOriginalSystem(wmsInReceiptTask.getOriginalSystem());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getOriginalSystemNumber())) {
                wmsInReceipt.setOriginalSystemNumber(wmsInReceiptTask.getOriginalSystemNumber());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getRequestPerson())) {
                wmsInReceipt.setRequestPerson(wmsInReceiptTask.getRequestPerson());
            }
            if (ObjectUtil.isEmpty(wmsInReceipt.getRequestTime())) {
                wmsInReceipt.setRequestTime(wmsInReceiptTask.getRequestTime());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getProductLine())) {
                wmsInReceipt.setProductLine(wmsInReceiptTask.getProductLine());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getTaskCode())) {
                wmsInReceipt.setTaskCode(wmsInReceiptTask.getTaskCode());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getSiteCode())) {
                wmsInReceipt.setSiteCode(wmsInReceiptTask.getSiteCode());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getMaterialArea())) {
                wmsInReceipt.setMaterialArea(wmsInReceiptTask.getMaterialArea());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getMaterialSite())) {
                wmsInReceipt.setMaterialSite(wmsInReceiptTask.getMaterialSite());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getMergeTaskCode())) {
                wmsInReceipt.setMergeTaskCode(wmsInReceiptTask.getMergeTaskCode());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getMergeProductLine())) {
                wmsInReceipt.setMergeProductLine(wmsInReceiptTask.getMergeProductLine());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getProductOrderNumber())) {
                wmsInReceipt.setProductOrderNumber(wmsInReceiptTask.getProductOrderNumber());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getUnitsNumber())) {
                wmsInReceipt.setUnitsNumber(wmsInReceiptTask.getUnitsNumber());
            }
            if (StrUtil.isEmpty(wmsInReceipt.getStackNumber())) {
                wmsInReceipt.setStackNumber(wmsInReceiptTask.getStackNumber());
            }
        }
    }

    /**
     * 创建入库单物料获取入库任务物料的公有属性
     */
    void initInReceiptMaterial(WmsInReceiptMaterial wmsInReceiptMaterial, String taskId) {
        if (StrUtil.isNotBlank(taskId)) {
            WmsInReceiptTaskMaterial taskMaterial = wmsInReceiptTaskMaterialMapper.selectOne(new LambdaQueryWrapper<WmsInReceiptTaskMaterial>()
                    .eq(WmsInReceiptTaskMaterial::getWmsInReceiptTaskId, taskId)
                    .eq(WmsInReceiptTaskMaterial::getWmsBasicMaterialId, wmsInReceiptMaterial.getWmsBasicMaterialId())
                    .eq(StrUtil.isNotBlank(wmsInReceiptMaterial.getBatchCode()), WmsInReceiptTaskMaterial::getBatchCode, wmsInReceiptMaterial.getBatchCode())
                    .eq(StrUtil.isNotBlank(wmsInReceiptMaterial.getOriginalSystemNumber()), WmsInReceiptTaskMaterial::getOriginalSystemLineNumber, wmsInReceiptMaterial.getOriginalSystemLineNumber())
                    .last("limit 1")
            );
            if (ObjectUtil.isNotNull(taskMaterial)) {
                BasicMaterial material = basicMaterialMapper.selectById(wmsInReceiptMaterial.getId());
                if (ObjectUtil.isNotNull(material)) {
                    if (ObjectUtil.isNull(taskMaterial.getAssistQuantity())) {
                        //设置辅数量
                        wmsInReceiptMaterial.setAssistQuantity(taskMaterial.getAssistQuantity());
                    }
                    if (ObjectUtil.isNull(taskMaterial.getUnitAssistId())) {
                        //辅单位
                        wmsInReceiptMaterial.setUnitAssistId(material.getAssistantUnitId());
                    }
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMain(WmsInReceipt wmsInReceipt, List<WmsInReceiptMaterial> wmsInReceiptMaterialList) {
        wmsInReceiptMaterialList.forEach(one->{
            if (StrUtil.isBlank(one.getWmsBasicWarehouseId())){
                throw new JeecgBootException("入库单缺少必填参数: 仓库");
            }
        });
        wmsInReceiptMapper.updateById(wmsInReceipt);

        List<WmsInReceiptMaterial> materials = wmsInReceiptMaterialMapper.selectList(new LambdaQueryWrapper<WmsInReceiptMaterial>()
                .eq(WmsInReceiptMaterial::getWmsInReceiptId, wmsInReceipt.getId()));

        //1.先删除子表数据
        wmsInReceiptMaterialMapper.deleteByMainId(wmsInReceipt.getId());
        for (WmsInReceiptMaterial material : materials) {
            basicMaterialService.updateUsedState(material.getWmsBasicMaterialId());
        }

        //2.子表数据重新插入
        if (wmsInReceiptMaterialList != null && wmsInReceiptMaterialList.size() > 0) {
            for (WmsInReceiptMaterial entity : wmsInReceiptMaterialList) {
                //外键设置
                entity.setWmsInReceiptId(wmsInReceipt.getId());
                wmsInReceiptMaterialMapper.insert(entity);
                basicMaterialService.updateUsedState(entity.getWmsBasicMaterialId());
            }
        }
        warehouseValid(wmsInReceipt.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delMain(String id) {
        List<WmsInReceiptMaterial> materials = wmsInReceiptMaterialMapper.selectList(new LambdaQueryWrapper<WmsInReceiptMaterial>()
                .eq(WmsInReceiptMaterial::getWmsInReceiptId, id));
        wmsInReceiptMaterialMapper.deleteByMainId(id);
        wmsInReceiptMapper.deleteById(id);
        for (WmsInReceiptMaterial material : materials) {
            basicMaterialService.updateUsedState(material.getWmsBasicMaterialId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delBatchMain(Collection<? extends Serializable> idList) {
        List<WmsInReceipt> wmsInReceipts = wmsInReceiptMapper.selectBatchIds(idList);
        List<String> collect = wmsInReceipts.stream().map(WmsInReceipt::getDocumentStatus).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(collect)) {
            if (collect.contains("200")) {
                throw new JeecgBootException("所选数据包含已完成的入库单,请重新选择");
            }
        }
        List<String> ids = wmsInReceipts.stream().map(WmsInReceipt::getId).collect(Collectors.toList());
        List<WmsInReceiptMaterial> materials = wmsInReceiptMaterialMapper.selectList(new LambdaQueryWrapper<WmsInReceiptMaterial>()
                .in(WmsInReceiptMaterial::getWmsInReceiptId, ids));

        for (Serializable id : idList) {
            wmsInReceiptMaterialMapper.deleteByMainId(id.toString());
            wmsInReceiptMapper.deleteById(id);
        }
        for (WmsInReceiptMaterial material : materials) {
            basicMaterialService.updateUsedState(material.getWmsBasicMaterialId());
        }
    }

    @Override
    public ListWmsInReceiptDTO listWmsInReceipt(String wmsInReceiptId) {
        ListWmsInReceiptDTO listWmsInReceiptDTO = wmsInReceiptMapper.listWmsInReceipt(wmsInReceiptId);
        if (ObjectUtil.isNotEmpty(listWmsInReceiptDTO)) {
            List<ListWmsInReceiptDetailDTO> list = listWmsInReceiptDTO.getList();
            if (ObjectUtil.isNotEmpty(list)) {
                list.forEach(dto -> {
                    List<DictModel> typeDicts = iSysBaseAPI.getDictItems("document_type");
                    typeDicts.forEach(type -> {
                        if (type.getValue().equals(dto.getDocumentType())) {
                            dto.setDocumentType_dictText(type.getText());
                        }
                    });
                    List<DictModel> statusDicts = iSysBaseAPI.getDictItems("document_status");
                    statusDicts.forEach(status -> {
                        if (status.getValue().equals(dto.getDocumentStatus())) {
                            dto.setDocumentStatus_dictText(status.getText());
                        }
                    });
                });
            }
        }
        return listWmsInReceiptDTO;
    }

    /**
     * 校验入库任务提交
     * 1.物料类型（弱控）：
     * 物料.物料分类 not in对应仓库可入物料类型,则提示：当前物料的物料分类跟仓库可入物料分类不匹配，是否可入库！用户点确定，则可入库，否则不可入库
     * 2.批次
     * 该行里的物料.启用批次管理=T，则保存的时候校验：XX物料批次号不可为空！
     *
     * @param id
     */
    private void warehouseValid(String id) {
        WmsInReceipt wmsInReceipt = wmsInReceiptMapper.selectById(id);
        List<ValidMaterialAndWarehouseTypeDTO> list = wmsInReceiptMaterialMapper.listByType(id);
        if (CollectionUtil.isNotEmpty(list)) {
            for (ValidMaterialAndWarehouseTypeDTO dto : list) {
//                if (!dto.getWarehouseType().contains(dto.getMaterialType())) {
//                    //todo 提示物料类型和仓库存放物料类型不一致
//                }
                if (ONE.equals(dto.getBatchManagementFlag()) && StrUtil.isEmpty(dto.getBatchCode())) {
                    throw new JeecgBootException(dto.getMaterialName() + " 启用了批次号管理，批次号不可为空");
                }
            }
        }
        wmsInReceipt.setDocumentStatus(String.valueOf(1));
        wmsInReceiptMapper.updateById(wmsInReceipt);
    }

    /**
     * 校验入库单提交
     *
     * @param id
     */
    private void warehouseDocValid(String id) {
        WmsInReceipt wmsInReceipt = wmsInReceiptMapper.selectById(id);
        wmsInReceipt.setDocumentStatus(TWO);
        wmsInReceiptMapper.updateById(wmsInReceipt);
    }

    /**
     * 校验出库任务提交
     *
     * @param id
     */
    private void outValid(String id) {
        WmsOutReceiptTask wmsOutReceiptTask = wmsOutReceiptTaskMapper.selectById(id);
        wmsOutReceiptTask.setDocumentStatus(TWO);
        wmsOutReceiptTaskMapper.updateById(wmsOutReceiptTask);
    }

    /**
     * 校验出库单提交
     *
     * @param id
     */
    private void outDocValid(String id) {
        WmsOutReceipt wmsOutReceipt = wmsOutReceiptMapper.selectById(id);
        wmsOutReceipt.setDocumentStatus(TWO);
        wmsOutReceiptMapper.updateById(wmsOutReceipt);
    }

    /**
     * 校验移库单
     *
     * @param id
     */
    private void moveDocValid(String id) {
        WmsMoveReceipt wmsMoveReceipt = wmsMoveReceiptMapper.selectById(id);
        wmsMoveReceipt.setDocumentStatus(TWO);
        wmsMoveReceiptMapper.updateById(wmsMoveReceipt);
    }

    @Override
    public void commit(String documentId, String documentStyle) {
        switch (documentStyle) {
            case "1":
                warehouseValid(documentId);
                break;
            case "2":
                warehouseDocValid(documentId);
                break;
            case "3":
                outValid(documentId);
                break;
            case "4":
                outDocValid(documentId);
                break;
            case "5":
                moveDocValid(documentId);
                break;
            default:
        }
    }

    @Override
    public List<ListByWarehouseIdResponseVO> listByWarehouseTaskId(String id) {
        List<WmsInReceiptTaskMaterial> wmsInReceiptTaskMaterials = wmsInReceiptTaskMaterialMapper.selectList(new LambdaQueryWrapper<WmsInReceiptTaskMaterial>()
                .eq(WmsInReceiptTaskMaterial::getWmsInReceiptTaskId, id));
        List<ListByWarehouseIdResponseVO> list = BeanUtil.copyToList(wmsInReceiptTaskMaterials, ListByWarehouseIdResponseVO.class);
        List<String> materialIds = list.stream().map(ListByWarehouseIdResponseVO::getWmsBasicMaterialId).collect(Collectors.toList());
        List<BasicMaterial> basicMaterials = basicMaterialMapper.selectList(new LambdaQueryWrapper<BasicMaterial>()
                .in(CollectionUtil.isNotEmpty(materialIds), BasicMaterial::getId, materialIds));
        for (ListByWarehouseIdResponseVO vo : list) {
            basicMaterials.forEach(o -> {
                if (o.getId().equals(vo.getWmsBasicMaterialId())) {
                    vo.setMaterialName(o.getName());
                    vo.setMaterialCode(o.getCode());
                    vo.setSpecification(o.getSpecification());
                }
            });
        }

        return list;
    }

    /**
     * 入库策略-场景一
     *
     * @param param
     * @return
     */
    @Override
    public WarehousingStrategyOneVO warehousingStrategyOne(WarehousingStrategyOneParamVO param) {
        WarehousingStrategyOneVO vo = new WarehousingStrategyOneVO();
        // 找仓库
        String warehouseId;
        if (StringUtils.isNotBlank(param.getWarehouseId())) {
            warehouseId = param.getWarehouseId();
        } else {
            if (StringUtils.isBlank(param.getMaterialId())) {
                return null;
            }
            BasicMaterial material = basicMaterialMapper.selectById(param.getMaterialId());
            warehouseId = material.getWarehouseId();
        }
        if (StringUtils.isBlank(warehouseId)) {
            return null;
        }
        vo.setWarehouseId(warehouseId);
        // 找库区
        List<DictModel> types = iSysBaseAPI.getDictItems("document_task");
        Map<String, String> typeMap = types.stream().collect(Collectors.toMap(DictModel::getValue, DictModel::getText, (key1, key2) -> key2));
        List<DictModel> sites = iSysBaseAPI.getDictItems("cross_cut_material_site");
        Map<String, String> siteMap = sites.stream().collect(Collectors.toMap(DictModel::getValue, DictModel::getText, (key1, key2) -> key2));

        List<WmsBasicWarehouseArea> areas = areaService.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, warehouseId));
        WmsBasicWarehouse warehouse = warehouseService.getById(warehouseId);
        if (warehouse == null) {
            return null;
        }
        // 未开启库区管理直接返回仓库
        if ("N".equals(warehouse.getIsUseArea())) {
            return vo;
        }
        // 按入库策略排序
        if ("1".equals(warehouse.getWarehouseStrategy())) {
            areas = areas.stream().sorted(Comparator.comparing(WmsBasicWarehouseArea::getOrderIndex)).collect(Collectors.toList());
        } else if ("2".equals(warehouse.getWarehouseStrategy())) {
            areas = areas.stream().sorted(Comparator.comparing(WmsBasicWarehouseArea::getOrderIndex).reversed()).collect(Collectors.toList());
        } else if ("3".equals(warehouse.getWarehouseStrategy())) {
            for (WmsBasicWarehouseArea location : areas) {
                location.setOrderIndex(Math.abs(location.getOrderIndex()));
            }
            areas = areas.stream().sorted(Comparator.comparing(WmsBasicWarehouseArea::getOrderIndex)).collect(Collectors.toList());
        } else if ("4".equals(warehouse.getWarehouseStrategy())) {
            for (WmsBasicWarehouseArea location : areas) {
                location.setOrderIndex(Math.abs(location.getOrderIndex()));
            }
            areas = areas.stream().sorted(Comparator.comparing(WmsBasicWarehouseArea::getOrderIndex).reversed()).collect(Collectors.toList());
        } else {
            return vo;
        }

        if (typeMap.get(param.getDocumentType()).startsWith("条料")) {
            if (StringUtils.isNotBlank(param.getProductSite())) {
                // 生产站点不为空
                for (WmsBasicWarehouseArea area : areas) {
                    String productSite = area.getProductSite();
                    if (StringUtils.isNotBlank(productSite)) {
                        String[] split = productSite.split(",");
                        for (int i = 0; i < split.length; i++) {
                            if (param.getProductSite().equals(siteMap.get(split[i]))) {
                                vo.setWarehouseAreaId(area.getId());
                                return vo;
                            }
                        }
                    }
                }
                return vo;
            } else {
                // 生产站点为空
                if (StringUtils.isBlank(param.getWidth())) {
                    return vo;
                }
                areas = areas.stream().filter(a -> {
                    // 宽度匹配宽度范围
                    BigDecimal widthMin = new BigDecimal(a.getWidthMin());
                    BigDecimal widthMax = new BigDecimal(a.getWidthMax());
                    BigDecimal width = new BigDecimal(param.getWidth());
                    return width.compareTo(widthMin) > -1 && widthMax.compareTo(width) > -1;
                }).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(areas)) {
                    return vo;
                }
                // 库存预留空位量
                areas = areas.stream().filter(a -> {
                    List<WmsRepertory> repertories = repertoryMapper.selectList(new LambdaQueryWrapper<WmsRepertory>()
                            .eq(WmsRepertory::getWmsBasicWarehouseAreaId, a.getId()));
                    Set<String> set = repertories.stream().map(WmsRepertory::getWmsBasicWarehouseAreaLocationId).collect(Collectors.toSet());
                    long count = locationService.count(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                            .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, a.getId()));
                    return new BigDecimal(count).subtract(new BigDecimal(set.size())).compareTo(new BigDecimal(a.getEmptyCapacity())) > -1;
                }).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(areas)) {
                    return vo;
                }
                vo.setWarehouseAreaId(areas.get(0).getId());
                return vo;
            }
        } else if (typeMap.get(param.getDocumentType()).startsWith("原卷")) {
            String shopSign;
            if (StringUtils.isBlank(param.getShopSign())) {
                shopSign = "1"; // 非刻痕库区
            } else {
                shopSign = "2"; // 刻痕库区
            }
            areas = areas.stream().filter(a -> shopSign.equals(a.getAreaType())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(areas)) {
                return vo;
            }
            if (StringUtils.isNotBlank(param.getProductSite())) {
                // 生产站点不为空
                for (WmsBasicWarehouseArea area : areas) {
                    String productSite = area.getProductSite();
                    if (StringUtils.isNotBlank(productSite)) {
                        String[] split = productSite.split(",");
                        for (int i = 0; i < split.length; i++) {
                            if (param.getProductSite().equals(siteMap.get(split[i]))) {
                                vo.setWarehouseAreaId(area.getId());
                                return vo;
                            }
                        }
                    }
                }
                return vo;
            }
            vo.setWarehouseAreaId(areas.get(0).getId());
            return vo;
        }
        return vo;
    }

    /**
     * 入库策略-场景二
     *
     * @param param
     * @return
     */
    @Override
    public WmsBasicWarehouseAreaLocation warehousingStrategy(WarehousingStrategyParamVO param) {
        if (StringUtils.isBlank(param.getBatchCode())) {
            return null;
        }
        WmsInReceiptTask task = wmsInReceiptTaskMapper.selectById(param.getInReceiptTaskId());
        List<DictModel> types = iSysBaseAPI.getDictItems("document_task");
        Map<String, String> typeMap = types.stream().collect(Collectors.toMap(DictModel::getValue, DictModel::getText, (key1, key2) -> key2));

        QueryWrapper<WmsInReceiptTaskMaterial> wrapper = new QueryWrapper<>();
        wrapper.eq("wms_in_receipt_task_id", param.getInReceiptTaskId());
        wrapper.eq("batch_code", param.getBatchCode());
        wrapper.last("limit 2");
        WmsInReceiptTaskMaterial material = wmsInReceiptTaskMaterialMapper.selectOne(wrapper);
        if (material == null || StringUtils.isBlank(material.getWmsBasicWarehouseId()) || StringUtils.isBlank(material.getWmsBasicWarehouseAreaId())) {
            return null;
        }
        WmsBasicWarehouse warehouse = warehouseService.getById(material.getWmsBasicWarehouseId());
        if (warehouse == null) {
            return null;
        }
        // 未开启库区管理返回空
        if ("N".equals(warehouse.getIsUseArea())) {
            return null;
        }

        // 不是临时移库并且启用的库位
        List<WmsBasicWarehouseAreaLocation> locations = locationService.list(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, material.getWmsBasicWarehouseAreaId())
                .eq(WmsBasicWarehouseAreaLocation::getIsTemporaryMove, "0")
                .eq(WmsBasicWarehouseAreaLocation::getStatus, "1"));
        // 有出库任务的库位
        List<WmsOutReceiptTask> outTasks = outReceiptTaskService.list(new LambdaQueryWrapper<WmsOutReceiptTask>()
                .in(WmsOutReceiptTask::getDocumentStatus, Arrays.asList("1", "2")));
        List<WmsBasicWarehouseAreaLocation> list = locations;
        if (CollectionUtils.isNotEmpty(outTasks)) {
            List<String> outIds = outTasks.stream().map(WmsOutReceiptTask::getId).collect(Collectors.toList());
            List<WmsOutReceiptTaskMaterial> outs = outReceiptTaskMaterialService.list(new LambdaQueryWrapper<WmsOutReceiptTaskMaterial>()
                    .in(WmsOutReceiptTaskMaterial::getWmsOutReceiptTaskId, outIds)
                    .ge(WmsOutReceiptTaskMaterial::getUnoutboundQuantity, 0));
            Set<String> set = outs.stream().map(WmsOutReceiptTaskMaterial::getWmsBasicWarehouseAreaLocationId).collect(Collectors.toSet());
            list = locations.stream().filter(a -> !set.contains(a.getId())).collect(Collectors.toList());
        }

        if (typeMap.get(task.getDocumentType()).startsWith("条料")) {
            // 库存容量和剩余宽度满足
            List<WmsBasicWarehouseAreaLocation> locationList = new ArrayList<>();
            if ("3".equals(warehouse.getOverCapacityWay())) {
                // 只有禁止入库才判断容量和宽度
                for (WmsBasicWarehouseAreaLocation location : list) {
                    List<WmsRepertory> repertories = repertoryMapper.selectList(new LambdaQueryWrapper<WmsRepertory>()
                            .eq(WmsRepertory::getWmsBasicWarehouseAreaLocationId, location.getId()));
                    // 判断宽度
                    if ("1".equals(warehouse.getOtherCapacityControl())) {
                        BigDecimal maxWidth = location.getMaxWidth();
                        BigDecimal width = repertories.stream().map(WmsRepertory::getWidth).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal bigDecimal = new BigDecimal(repertories.size() + 2);
                        BigDecimal toolLength = warehouse.getToolLength();
                        BigDecimal s = maxWidth.subtract(width).subtract(bigDecimal.multiply(toolLength));
                        if (s.compareTo(material.getWidth()) <= -1) {
                            continue;
                        }
                    }
                    // 判断库存容量
                    if (StringUtils.isNotBlank(warehouse.getCapacityControlUnit())) {
                        // 库存单位
                        if (Arrays.asList(warehouse.getCapacityControlUnit().split(",")).contains("1")) {
                            BigDecimal stockQuantity = repertories.stream().map(WmsRepertory::getStockQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                            BigDecimal maxCapacity = location.getMaxCapacity();
                            if (maxCapacity.subtract(stockQuantity).compareTo(material.getUnwarehousedQuantity()) <= -1) {
                                continue;
                            }
                        }
                        // 辅助单位
                        if (Arrays.asList(warehouse.getCapacityControlUnit().split(",")).contains("2")) {
                            BigDecimal stockQuantity = repertories.stream().map(WmsRepertory::getStockQuantitySub).reduce(BigDecimal.ZERO, BigDecimal::add);
                            BigDecimal maxCapacity = location.getMaxCapacityAssist();
                            if (maxCapacity.subtract(stockQuantity).compareTo(material.getUnwarehousedQuantityAssist()) <= -1) {
                                continue;
                            }
                        }
                    }
                    locationList.add(location);
                }
            } else {
                locationList = list;
            }
            List<WmsBasicWarehouseAreaLocation> datumList = this.getDatumList(material.getWmsBasicWarehouseAreaId(), locationList);
            if (CollectionUtil.isEmpty(datumList)) {
                return null;
            }
            datumList.get(0).setWmsBasicWarehouseId(material.getWmsBasicWarehouseId());
            datumList.get(0).setWmsBasicWarehouseName(warehouse.getName());
            datumList.get(0).setWmsBasicWarehouseAreaName(areaService.getById(material.getWmsBasicWarehouseAreaId()).getName());
            // 只有PDA调用时才亮灯
            if ("1".equals(param.getIsLight())) {
                this.light(datumList.get(0));
            }
            return datumList.get(0);
        } else if (typeMap.get(task.getDocumentType()).startsWith("原卷")) {
            List<WmsBasicWarehouseAreaLocation> locationList = new ArrayList<>();
            for (WmsBasicWarehouseAreaLocation location : list) {
                List<WmsRepertory> repertories = repertoryMapper.selectList(new LambdaQueryWrapper<WmsRepertory>()
                        .eq(WmsRepertory::getWmsBasicWarehouseAreaLocationId, location.getId()));
                // 判断库存容量
                if (StringUtils.isNotBlank(warehouse.getCapacityControlUnit())) {
                    // 库存单位
                    if (Arrays.asList(warehouse.getCapacityControlUnit().split(",")).contains("1")) {
                        BigDecimal stockQuantity = repertories.stream().map(WmsRepertory::getStockQuantity).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal maxCapacity = location.getMaxCapacity();
                        if (maxCapacity.subtract(stockQuantity).compareTo(material.getUnwarehousedQuantity()) <= -1) {
                            continue;
                        }
                    }
                    // 辅助单位
                    if (Arrays.asList(warehouse.getCapacityControlUnit().split(",")).contains("2")) {
                        BigDecimal stockQuantity = repertories.stream().map(WmsRepertory::getStockQuantitySub).reduce(BigDecimal.ZERO, BigDecimal::add);
                        BigDecimal maxCapacity = location.getMaxCapacityAssist();
                        if (maxCapacity.subtract(stockQuantity).compareTo(material.getUnwarehousedQuantityAssist()) <= -1) {
                            continue;
                        }
                    }
                }
                locationList.add(location);
            }
            if (CollectionUtils.isEmpty(locationList)) {
                return null;
            }
            if (locationList.size() > 1) {
                // todo 优化
                if ("1".equals(warehouse.getWarehouseStrategy())) {
                    locationList = locationList.stream().sorted(Comparator.comparing(WmsBasicWarehouseAreaLocation::getOrderIndex)).collect(Collectors.toList());
                } else if ("2".equals(warehouse.getWarehouseStrategy())) {
                    locationList = locationList.stream().sorted(Comparator.comparing(WmsBasicWarehouseAreaLocation::getOrderIndex).reversed()).collect(Collectors.toList());
                } else if ("3".equals(warehouse.getWarehouseStrategy())) {
                    for (WmsBasicWarehouseAreaLocation location : locationList) {
                        location.setOrderIndex(Math.abs(location.getOrderIndex()));
                    }
                    locationList = locationList.stream().sorted(Comparator.comparing(WmsBasicWarehouseAreaLocation::getOrderIndex)).collect(Collectors.toList());
                } else if ("4".equals(warehouse.getWarehouseStrategy())) {
                    for (WmsBasicWarehouseAreaLocation location : locationList) {
                        location.setOrderIndex(Math.abs(location.getOrderIndex()));
                    }
                    locationList = locationList.stream().sorted(Comparator.comparing(WmsBasicWarehouseAreaLocation::getOrderIndex).reversed()).collect(Collectors.toList());
                } else {
                    return null;
                }
            }
            locationList.get(0).setWmsBasicWarehouseId(material.getWmsBasicWarehouseId());
            locationList.get(0).setWmsBasicWarehouseName(warehouse.getName());
            locationList.get(0).setWmsBasicWarehouseAreaName(areaService.getById(material.getWmsBasicWarehouseAreaId()).getName());
            // 只有PDA调用时才亮灯
            if ("1".equals(param.getIsLight())) {
                this.light(locationList.get(0));
            }
            return locationList.get(0);
        }
        return null;
    }

    @Override
    public IPage<WmsInReceipt> listByPage(Page<WmsInReceipt> pageList, WmsInReceiptQueryVO param) {
        if (ObjectUtil.isNotEmpty(param.getDocumentType())) {
            List<String> documentTypeList = Arrays.asList(StringUtils.split(param.getDocumentType(), ","));
            param.setDocumentTypeList(documentTypeList);
        }
        if (StrUtil.isNotBlank(param.getDocumentStatus())) {
            List<String> documentStatusList = Arrays.asList(StringUtils.split(param.getDocumentStatus(), ","));
            param.setDocumentStatusList(documentStatusList);
        }
        setRoleAuth(param);
        return wmsInReceiptMapper.getPage(pageList, param);
    }
    void setRoleAuth(WmsInReceiptQueryVO param){
        //校验角色
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if(Objects.isNull(sysUser)){
            param.setManageWarehouseIdList(Arrays.asList("-1"));
            param.setAdminFlag(false);
        }else if(StrUtil.contains(sysUser.getUsername(),"admin")){
            param.setManageWarehouseIdList(new ArrayList<>());
            param.setAdminFlag(true);
        }else{
            //不是管理员
            List<String> warehouseListByUserId = wmsBasicWarehouseGroupUserMapper.getWarehouseListByUserId(sysUser.getId());
            warehouseListByUserId.add("-1");
            param.setManageWarehouseIdList(warehouseListByUserId);
            param.setAdminFlag(false);
        }
    }

    /**
     * 补单-查询所有未创建入库单的物料信息
     * @param unCreateReqVO
     * @return
     */
    @Override
    public List<UnCreateInVO> listAllUnCreate(UnCreateReqVO unCreateReqVO) {

        List<UnCreateInVO> unCreateInVOList = wmsInReceiptMaterialMapper.listAllUnCreateTaskMaterial(unCreateReqVO.getTaskId(), null,unCreateReqVO.getMaterialName());
        if(CollectionUtil.isEmpty(unCreateInVOList)){
            return unCreateInVOList;
        }else{
            List<String> taskMaterialIdList = unCreateReqVO.getTaskMaterialIdList();
            if(!CollectionUtil.isEmpty(taskMaterialIdList)){
                unCreateInVOList = unCreateInVOList.stream().filter(o ->
                        !CollectionUtil.contains(taskMaterialIdList,o.getWmsInReceiptTaskMaterialId())
                ).collect(Collectors.toList());
            }
            if(CollectionUtil.isEmpty(unCreateInVOList)){
                return unCreateInVOList;
            }else{
                //设置上游单据 上游行号等数据
                WmsInReceiptTask wmsInReceiptTask = wmsInReceiptTaskService.getById(unCreateReqVO.getTaskId());
                if(!Objects.isNull(wmsInReceiptTask)){
                    for(UnCreateInVO inVO:unCreateInVOList){
                        inVO.setUpstreamDocuments("入库任务");
                        inVO.setUpstreamNumber(wmsInReceiptTask.getDocumentCode());
                        inVO.setUpstreamLineNumber(unCreateInVOList.indexOf(inVO)+1+"");
                    }
                }
                unCreateInVOList = unCreateInVOList.stream().filter(o ->
                        {
                            BigDecimal unwarehousedQuantity=Objects.isNull(o.getUnwarehousedQuantity())?BigDecimal.ZERO:o.getUnwarehousedQuantity();
                            return BigDecimal.ZERO.compareTo(unwarehousedQuantity)!=0;
                        }
                ).collect(Collectors.toList());
                return unCreateInVOList;
            }
        }
    }

    /**
     * 选单-查询入库单需要的物料信息
     * @param materialIdList
     * @return
     */
    @Override
    public List<WmsInReceiptMaterialResponseVO> getUnCreateMaterials(List<String> materialIdList) {
        List<WmsInReceiptTaskMaterial> taskMaterialList = wmsInReceiptTaskMaterialMapper.selectList(new LambdaQueryWrapper<WmsInReceiptTaskMaterial>()
                .in(WmsInReceiptTaskMaterial::getId,materialIdList)
        );
        if(CollectionUtil.isEmpty(taskMaterialList)){
            return Collections.emptyList();
        }else{
            List<WmsInReceiptMaterialResponseVO> finalList=new ArrayList<>();
            WmsInReceiptTaskMaterial tempTaskMaterial = taskMaterialList.get(0);
            WmsInReceiptTask task = wmsInReceiptTaskService.getById(tempTaskMaterial.getWmsInReceiptTaskId());
            for(WmsInReceiptTaskMaterial taskMaterial:taskMaterialList){
                WmsInReceiptMaterialResponseVO responseVO = cn.hutool.core.bean.BeanUtil.toBean(taskMaterial, WmsInReceiptMaterialResponseVO.class);
                responseVO.setReceivableQuantity(taskMaterial.getPlanQuantity());
                //设置物料信息
                BasicMaterial material = basicMaterialMapper.selectById(responseVO.getWmsBasicMaterialId());
                if(!Objects.isNull(material)){
                    responseVO.setMaterialName(material.getName());
                    responseVO.setMaterialCode(material.getCode());
                    responseVO.setSpecification(material.getSpecification());
                }
                responseVO.setWmsInReceiptTaskMaterialId(taskMaterial.getId());
                //设置上游单据 上有单号
                responseVO.setUpstreamDocuments("入库任务");
                if(!Objects.isNull(task)){
                    responseVO.setUpstreamNumber(task.getDocumentCode());
                }
                finalList.add(responseVO);
            }

            return finalList;
        }
    }

    @Override
    public Result<Void> inReceiptTransfer(String id) {
        WmsInReceipt po = wmsInReceiptMapper.selectById(id);
        List responseDTOS = new ArrayList<>();
        try {
            if (ArrayUtil.contains(deliveryType,po.getDocumentType())){
                List<WmsInReceiptMaterial> list = wmsInReceiptMaterialMapper.selectList(new LambdaQueryWrapper<WmsInReceiptMaterial>()
                        .eq(WmsInReceiptMaterial::getWmsInReceiptId, po.getId())
                );
                responseDTOS = sapOperateService.warehouseByOrder(po.getId(),list);
            }else {
                responseDTOS = sapOperateService.warehouseByOrder(po.getId());
            }
        }catch (Exception e){
            //更新过账状态 过账失败
            wmsInReceiptTaskService.updateTransferStatus(SimpleDocumentTypeEnum.IN_RECEIPT,null,po.getId(), TransferStatusEnum.TRANSFER_FAIL);
            return Result.error("过账失败: " + e.getMessage());
        }
        if (CollectionUtil.isNotEmpty(responseDTOS)) {
            Object res = responseDTOS.get(0);
            String jsonStr = JSON.toJSONString(res);
            JSONObject jsonObject = JSONObject.parseObject(jsonStr);
            log.info("解析之后:{}",jsonObject);
            if ("E".equals(jsonObject.get("result"))) {
                //更新过账状态 过账失败
                wmsInReceiptTaskService.updateTransferStatus(SimpleDocumentTypeEnum.IN_RECEIPT,null,po.getId(), TransferStatusEnum.TRANSFER_FAIL);
                return Result.error("过账失败: " + jsonObject.get("message"));
            }else {
                //更新过账状态 过账成功
                wmsInReceiptTaskService.updateTransferStatus(SimpleDocumentTypeEnum.IN_RECEIPT,null,po.getId(), TransferStatusEnum.TRANSFER_SUCCESS);
                //将入库单状态改为已完成
                this.update(new LambdaUpdateWrapper<WmsInReceipt>()
                        .set(WmsInReceipt::getDocumentStatus,DocumentStatusEnum.COMPLETE.getCode())
                        .eq(WmsInReceipt::getId,id)
                );
                //根据单据id获取任务id
                WmsInReceipt receipt = wmsInReceiptMapper.selectById(po.getId());
                inBoundBeanUtils.updateTaskWareHouseStatus(receipt.getWmsInReceiptTaskId());
                //调用回调
                workFlowService.backAutoCommit(receipt.getWmsInReceiptTaskId(), receipt);
                log.info("入库过账结束了");
                return Result.OK();
            }
        }
        return Result.OK();
    }

    /**
     * 盘盈单-过账
     * @param id
     * @return
     */
    @Override
    public Result<Void> pydPassSAP(String id) {
        List<InventoryAdjustRequestDTO> list = new ArrayList<>();
        List<WmsInReceiptMaterial> receiptMaterials = wmsInReceiptMaterialMapper.selectByMainId(id);
        for (WmsInReceiptMaterial material : receiptMaterials) {
            InventoryAdjustRequestDTO dto = new InventoryAdjustRequestDTO();
            BasicMaterial byId = basicMaterialService.getById(material.getWmsBasicMaterialId());
            dto.setMaterialCode(byId.getCode());
            WmsSapWarehouseMap one = sapWarehouseMapMapper.selectOne(new LambdaQueryWrapper<WmsSapWarehouseMap>()
                    .eq(WmsSapWarehouseMap::getWmsBasicWarehouseId, material.getWmsBasicWarehouseId())
                    .last("limit 1"));
            if (one == null) {
                WmsBasicWarehouse warehouse = warehouseService.getById(material.getWmsBasicWarehouseId());
                wmsInReceiptTaskService.updateTransferStatus(SimpleDocumentTypeEnum.IN_RECEIPT,null, id, TransferStatusEnum.TRANSFER_FAIL);
                return Result.error("过账失败，仓库【" + warehouse.getName() + "】没有配置对应的sap库位");
            }
            dto.setLocation(one.getSapLocation());
            WmsSapLocation sapLocation = sapLocationService.getOne(new LambdaQueryWrapper<WmsSapLocation>()
                    .eq(WmsSapLocation::getCode, one.getSapLocation())
                    .last("limit 1"));
            if (sapLocation == null) {
                WmsBasicWarehouse warehouse = warehouseService.getById(material.getWmsBasicWarehouseId());
                wmsInReceiptTaskService.updateTransferStatus(SimpleDocumentTypeEnum.IN_RECEIPT,null, id, TransferStatusEnum.TRANSFER_FAIL);
                return Result.error("过账失败，仓库【" + warehouse.getName() + "】没有配置对应的工厂");
            }
            dto.setFactory(sapLocation.getFactory());
            dto.setSaleOrderCode(material.getSaleOrderNumber());
            dto.setSaleOrderCodeLine(material.getSaleOrderLineNumber());
            dto.setAdjustNumber(material.getReceivableQuantity());
            list.add(dto);
        }
        List<InventoryUpdateResponseDTO> dtos = new ArrayList<>();
        try {
            dtos = sapDockingRepeaterService.inventoryCountAdjustment(list);
        } catch (Exception e) {
            wmsInReceiptTaskService.updateTransferStatus(SimpleDocumentTypeEnum.IN_RECEIPT,null, id, TransferStatusEnum.TRANSFER_FAIL);
            return Result.error("盘盈单过账sap失败: " + e.getMessage());
        }
        if (CollectionUtil.isNotEmpty(dtos)) {
            InventoryUpdateResponseDTO res = dtos.get(0);
            if ("E".equals(res.getResult())) {
                wmsInReceiptTaskService.updateTransferStatus(SimpleDocumentTypeEnum.IN_RECEIPT,null, id, TransferStatusEnum.TRANSFER_FAIL);
                return Result.error("盘盈单过账sap失败: " + res.getMessage());
            }
        }
        return null;
    }

    /**
     * 基准点往四周扩散算法
     *
     * @param areaId
     * @return
     */
    private List<WmsBasicWarehouseAreaLocation> getDatumList(String areaId, List<WmsBasicWarehouseAreaLocation> locations) {
        WmsBasicWarehouseAreaLocation datum = locationService.getOne(new LambdaQueryWrapper<WmsBasicWarehouseAreaLocation>()
                .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, areaId)
                .eq(WmsBasicWarehouseAreaLocation::getIsDatum, "1")
                .last("limit 1"));
        if (datum == null) {
            return Collections.emptyList();
        }
        String[] datumArray = datum.getCode().split("-");
        if (datumArray.length < 4) {
            return Collections.emptyList();
        }
        BigDecimal datum1 = new BigDecimal(datumArray[datumArray.length - 3]);
        BigDecimal datum2 = new BigDecimal(datumArray[datumArray.length - 2]);
        for (WmsBasicWarehouseAreaLocation location : locations) {
            String[] split = location.getCode().split("-");
            BigDecimal decimal1 = new BigDecimal(split[split.length - 3]);
            BigDecimal decimal2 = new BigDecimal(split[split.length - 2]);
            BigDecimal decimal3 = new BigDecimal(split[split.length - 1]);
            BigDecimal subtract1 = decimal1.subtract(datum1);
            BigDecimal subtract2 = decimal2.subtract(datum2);
            BigDecimal result = subtract1.multiply(subtract1).add(subtract2.multiply(subtract2)).multiply(BigDecimal.valueOf(10)).add(decimal3);
            location.setResult(result);
        }
        List<WmsBasicWarehouseAreaLocation> list = locations.stream().sorted(Comparator.comparing(WmsBasicWarehouseAreaLocation::getResult)).collect(Collectors.toList());
        return list;
    }

    /**
     * 亮灯
     */
    private void light(WmsBasicWarehouseAreaLocation location) {
        List<WmsLightConfig> list = lightConfigMapper.selectList(new LambdaQueryWrapper<WmsLightConfig>()
                .eq(WmsLightConfig::getWmsBasicWarehouseAreaLocationId, location.getId()));
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        LightRequestVO vo = new LightRequestVO();
        vo.setState(1);
        vo.setLightColor(64);
        vo.setLocationId(list.get(0).getLocationId()+"-"+list.get(0).getSiteCode());
        List<LightRequestVO> vos = new ArrayList<>();
        vos.add(vo);
        lightIBSDockingService.lightIBS(vos);
    }
}
